/* 
 * File:   meshaligner.h
 * Author: boyan
 *
 * Created on March 18, 2009, 1:13 PM
 */

#ifndef _MESHALIGNER_H
#define	_MESHALIGNER_H

// standard includes
#include <vector>
#include <iostream>
#include <iomanip>
#include <fstream>

// mesquite includes
#include <MeshInterface.hpp>
#include <MsqError.hpp>

// in-house includes
#include "AlignDomain.h"
#include "VertChImpl.h"

class MeshAligner
{
private:
    void set_domain_dim(void);
    unsigned short domain_dim;
    Mesquite::MsqError &err;
public:

    MeshAligner(Mesquite::Mesh *mesh, AlignDomain *domain, Mesquite::MsqError &e)
    : err(e), my_mesh(mesh), my_domain(domain), initialized(false)
    {
        set_domain_dim();
        set_vertices_chooser();
    }

    void set_vertices_chooser(VerticesChooser *new_chooser = 0);
    void align();

    // align() basically does {initialize(); choose_vertices(); move_vertices();}
    void initialize();
    void choose_vertices();
    void move_vertices();

    template < int (*h2n) (Mesquite::Mesh::VertexHandle) >
    void dump_levels(const char *filename)
    {
        std::ofstream lsfile(filename);
        LevelsetCode_array::const_iterator tom;
        for (tom = levelset.begin(); tom != levelset.end(); ++tom)
            lsfile << h2n(tom->first) << ",    "
            << (int) tom->second << std::endl;
        lsfile.close();
    }

    LevelsetCode_array &get_levels();

    virtual ~MeshAligner()
    {
    }

protected:
    Mesquite::Mesh *my_mesh;
    AlignDomain *my_domain;
    bool initialized;
    LevelsetCode_array levelset;
    VerticesChooser *chooser;

    void fill_levelset_codes();
};

inline LevelsetCode_array & MeshAligner::get_levels()
{
    return levelset;
}


#endif	/* _MESHALIGNER_H */

